package cn.dai.single;


public class Singleton{}

// 饿汉式第一种
class HungryMan01 {

    // 私有构造器
    private HungryMan01 (){}

    // 静态固定实例
    private static final HungryMan01 instance = new HungryMan01();

    // 提供公开的提供实例方法即可
    public static HungryMan01 getInstance() {
        return instance;
    }
}

// 饿汉式第二种
class HungryMan02 {

    // 私有构造器
    private HungryMan02(){}

    // 声明单例实例
    private static HungryMan02 instance;

    // 交给静态块加载
    static { instance = new HungryMan02(); }

    // 一样的获取方法
    public static HungryMan02 getInstance(){ return instance; }
}

// 懒汉式第一种
class LazyMan01 {

    private LazyMan01(){}

    private static LazyMan01 instance;

    // 如果instance为空 就new出来，反之直接返回
    public static LazyMan01 getInstance(){
        if (instance == null) instance = new LazyMan01();
        return instance;
    }
}

// 懒汉式第二种
class LazyMan02 {

    private LazyMan02(){}

    private static LazyMan02 instance;

    // 给方法加锁，同步处理化
    public static synchronized LazyMan02 getInstance(){
        if (instance == null) instance = new LazyMan02();
        return instance;
    }
}

// 懒汉式第三种
class LazyMan03 {

    private LazyMan03(){}

    private static LazyMan03 instance;

    // 经过判断后枷锁实例，多线程直接跳过判断获取，还是会创建实例
    public static LazyMan03 getInstance(){
        if (instance == null) synchronized (LazyMan03.class) { instance = new LazyMan03();}
        return instance;
    }
}

// 懒汉式第四种
class LazyMan04 {

    private LazyMan04 (){}

    // 设置可见
    private static volatile LazyMan04 instance;

    // 二次检查
    public static LazyMan04 getInstance(){
        if (instance == null) synchronized (LazyMan04.class) {
            if (instance == null) instance = new LazyMan04();
        }
        return instance;
    }
}

// 静态内部类
class StaticInnerClass {

    private StaticInnerClass(){}

    // 静态内部类不会重复加载，其静态属性也如此
    private static final class SingleInstanceClass{
        private static final StaticInnerClass INSTANCE = new StaticInnerClass();
    }

    // 返回内部类的属性实例即可
    public static StaticInnerClass getInstance(){
        return SingleInstanceClass.INSTANCE;
    }
}

// 枚举类
enum EnumerationClass{

    INSTANCE;

    public void ok(){
        System.out.println("ok!");
    }
}